// **************************************************************
// COPYRIGHT(c)2015, Xidian University
// All rights reserved.
//
// IP LIB INDEX :  
// IP Name      :      
// File name    :  
// Module name  :  
// Full name    :  
// Time         : 2016 
// Author       : Wang-Weina 
// Email        : 327422289@qq.com 
// Data         : 
// Version      : V 1.0 
// 
// Abstract     :
// Called by    :  
// 
// Modification history
// -----------------------------------------------------------------
// 
// 
//
// *****************************************************************

// *******************
// TIMESCALE
// ******************* 
`timescale 1ns/1ps 

// *******************
// INFORMATION
// *******************

//*******************
//DEFINE(s)
//*******************
//`define UDLY 1    //Unit delay, for non-blocking assignments in sequential logic

//*******************
//DEFINE MODULE PORT
//*******************
module  pe1
    #(parameter RULE_N     = 8 ,
      parameter PE_FIELD_L = 4 ,
      parameter MODIFY_L   = 16,
      parameter PE_NUM     = 1 ,
      parameter RAM_NUM    = 1
    )
    (
    input wire clk,
    input wire rst_n,

    input wire lookup_en,
    input wire lookup_en1,
    input wire[PE_FIELD_L-1:0] rule_in1,
    input wire[RULE_N-1:0] bv_in1,
    input wire modify_en,
    input wire[2:0] modify_loc,
    input wire[MODIFY_L-1:0] modify_value,

    output reg en_out1,
    output wire[MODIFY_L-1:0] cpu_data_o,
    output reg lookup_done1,
    output reg[RULE_N-1:0] bv_out1,
    output reg[PE_FIELD_L-1:0] rule_out1
    // output reg lookup_done1,
    // output reg lookup_done2
    );

//*******************
//DEFINE LOCAL PARAMETER
//*******************
//parameter(s)
//*********************
//INNER SIGNAL DECLARATION
//*********************
//REGS
   
reg[7 :0] bv_out1_r;
// reg lookup_en1_ff;
//WIRES
wire[RULE_N-1:0] ram_out1;

//*********************
//INSTANTCE MODULE
//*********************
 dual_ram #(.RAM_NUM(RAM_NUM))
 U_ram1 (
    .clk(clk),
    .rst_n(rst_n),
    // .lookup_en1(lookup_en1_ff),
    .modify_en(modify_en),
    .modify_loc(modify_loc),
    .modify_value(modify_value),
    .dout2(cpu_data_o),
    .addr1(rule_in1),
    .dout1(ram_out1)
    );
 
 

//*********************
//MAIN CORE
//********************* 
//******************rule_ina****************
//每一个匹配模块之只查找匹配字段的一部分


//******************bv_out1******************
//和上一级PE的输出结果相与才是最终的结果   横向传递的参数
// assign bv_out1 =(lookup_en&lookup_en1==1)?bv_in1&ram_out1:8'b0;
// assign bv_out2 =(lookup_en&lookup_en2==1)?bv_in2&ram_out2:8'b0;
always @(*) 
begin
  if(~rst_n)
    bv_out1_r = 8'h0;
  else if(lookup_en1)
    bv_out1_r = ram_out1 & bv_in1;      
  else 
    bv_out1_r = 8'h0;
end
//上一级没有输出结果全0 ，本级无须继续查找
always@(posedge clk or negedge rst_n)
    begin
        if(~rst_n)
          begin
          bv_out1          <=0;
          // rule_out1        <=0;
          end 
        else if(lookup_en1==0)
          begin 
           bv_out1          <=0;
          // rule_out1        <=rule_out1;
          end
        else
          begin 
          bv_out1          <= bv_out1_r;
          // rule_out1        <= rule_in1;
          end 
    end

always @(posedge clk or negedge rst_n)
  begin
      if(~rst_n)
        begin
            rule_out1 <= 0;
        end
      else 
        begin
            rule_out1 <=rule_in1;
        end
  end
//如果本级查找没有输出则查找失败，下一级不需要查找
always@(posedge clk or negedge rst_n)
  begin
    if(~rst_n)
      en_out1 <= 1'b0;
    else if(bv_out1_r!=0 && lookup_en1)
      en_out1 <= 1'b1;
    else 
      en_out1 <= 1'b0;
  end 
always@(posedge clk or negedge rst_n)
  begin
    if(~rst_n)
      lookup_done1 <= 0;
    else 
      lookup_done1 <= lookup_en;
  end

//******************纵向传递的参数********************


endmodule    // hookup byte controller block